package cn.yujiago.api.alipay.controller;

import cn.yujiago.api.alipay.pojo.QRCode;
import cn.yujiago.api.alipay.service.AlipayService;
import cn.yujiago.api.alipay.util.AlipayUtil;
import com.alipay.api.domain.QRcode;
import com.alipay.api.domain.TradeFundBill;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.TradeStatus;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.alipay.demo.trade.utils.ZxingUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Controller
public class PayController {

    private static Map<String, String> payStatus = new ConcurrentHashMap<>();

    @Autowired
    private AlipayService alipayService;

    @PostMapping("/getQRCode")
    public String getQRCode(QRCode qrCode, HttpServletRequest request, HttpSession session){

        Log log = LogFactory.getLog("trade_precreate");

        if(StringUtils.isNotEmpty(qrCode.getOutTradeNo())){

            AlipayF2FPrecreateResult result = alipayService.generateQRCode(qrCode);
            StringBuffer output = new StringBuffer();

            String status = AlipayUtil.checkStatus(result.getTradeStatus());
            log.info(status);

            if(result.getTradeStatus().equals(TradeStatus.SUCCESS)){
                AlipayTradePrecreateResponse res = result.getResponse();

                String basePath = request.getSession().getServletContext().getRealPath("/");
                String fileName = String.format("images%sqr-%s.png", File.separator, res.getOutTradeNo());
                String filePath = new StringBuilder(basePath).append(fileName).toString();

                session.setAttribute("qrcode", fileName);
                // 生成二维码时，将订单号存入session，用于检测是否支付成功后页面跳转
                session.setAttribute("outTradeNo", qrCode.getOutTradeNo());

                output.append("<img src=\"" + fileName + "\" />")
                        .append("filePath:" + filePath);

                ZxingUtils.getQRCodeImge(res.getQrCode(), 256, filePath);
            }

            output.append(result.getResponse().getBody());
            session.setAttribute("detail", output.toString());
            return "alipay/trade_qcode";
        }
        return "error/4xx";
    }

    @RequestMapping("/query")
    public String query(String outTradeNo, Map<String, Object> map){
        Log log = LogFactory.getLog("trade_query");

        if(outTradeNo != null){

            AlipayF2FQueryResult result = AlipayUtil.query(outTradeNo);

            String statusTip = AlipayUtil.checkStatus(result.getTradeStatus());
            log.info(statusTip);

            if(result.getTradeStatus().equals(TradeStatus.SUCCESS)){
                AlipayTradeQueryResponse resp = result.getResponse();

                log.info(resp.getTradeStatus());

                map.put("trade_no", resp.getTradeNo());
                map.put("buyer_logon_id", resp.getBuyerLogonId());
                map.put("total_amount", resp.getTotalAmount());
                map.put("point_amount", resp.getPointAmount());
                map.put("buyer_pay_amount", resp.getBuyerPayAmount());
                map.put("send_pay_date", resp.getSendPayDate());
            }

            return "alipay/trade_showQuery";
        }
        return "error/4xx";
    }

    @RequestMapping("/refund")
    public String refund(String outTradeNo, String refundAmount, String refundReason, String outRequestNo, String storeId, Map<String, Object> map){

        Log log = LogFactory.getLog("trade_refund");

        if(outTradeNo != null){
            // (必填) 商户门店编号，退款情况下可以为商家后台提供退款权限判定和统计等作用，详询支付宝技术支持
            storeId = "test_store_id";

            AlipayF2FRefundResult result = AlipayUtil.refund(outTradeNo, refundAmount, refundReason, outRequestNo, storeId);

            // 商户订单号
            map.put("out_trade_no", result.getResponse().getOutTradeNo());
            // 用户的登录id
            map.put("buyer_logon_id", result.getResponse().getBuyerLogonId());
            // 退款总金额
            map.put("refund_fee", result.getResponse().getRefundFee());
            // 退款支付时间
            map.put("gmt_refund_pay", result.getResponse().getGmtRefundPay());

            String tradeStatus = AlipayUtil.checkStatus(result.getTradeStatus());
            log.info(tradeStatus);

            return "alipay/trade_refundResult";
        }
        log.info("订单号不能为空!!!");
        return "error/4xx";
    }

    @PostMapping("/alipay_callback")
    @ResponseBody
    public String callback(HttpServletRequest request){

        Log log = LogFactory.getLog("trade_callback");

        log.info("支付宝回调");

        Map<String, String> params = AlipayUtil.transferCallBackResultToMap(request);

        // 将对应交易ID的状态存放入map中
        payStatus.put(params.get("out_trade_no"), "TRADE_SUCCESS");

        return null;
    }

    @GetMapping("/checkPayResult")
    @ResponseBody
    public Map<String, String> checkPayResult(@RequestParam("outTradeNo") String outTradeNo){

        Map<String, String> map = new HashMap<>();

        if(StringUtils.isNotEmpty(outTradeNo)){
            map.put("status", payStatus.get(outTradeNo));
        }

        return map;
    }
}
